package penguin.masking;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wuxh
 * @version 1.0.0
 */
public abstract class WordManager implements RecyclableResource, Runnable {

    long reloadTimes = 60 * 1000;//每一分钟执行重加载词典
    long loadTime = 0;
    private volatile boolean scanning = false;
    private AtomicInteger runTimes = new AtomicInteger(0);

    /**
     * 重加载词典间隔时间，单位分钟
     *
     * @param min
     */
    public void setReloadTimes(int min) {
        this.loadTime = min * 60 * 1000;
    }

    public void start() {
        long currentTime = System.currentTimeMillis();
        //隔一段时间执行一次
        if (currentTime - loadTime < reloadTimes) {
            return;
        }
        loadTime = System.currentTimeMillis();
        if (scanning) {
            return;
        }
        scanning = true;
        new Thread(this).start();
    }

    @Override
    public void run() {
        try {
            if (runTimes.getAndIncrement() == 0) {
                this.refreshWords();
            }
        } finally {
            runTimes.decrementAndGet();
            scanning = false;
        }
    }

    public SensitiveWordMasking matchMasking(String userName) {
        if (userName == null || userMaskingMap.isEmpty() || !MaskingContext.context().isMultiple()) {
            return defaultMasking;
        }
        SensitiveWordMasking masking = userMaskingMap.get(userName);
        return masking == null ? defaultMasking : masking;
    }

    public SensitiveWordMasking getDefaultMasking() {
        return defaultMasking;
    }

    private SensitiveWordMasking defaultMasking = null;
    private Map<String, SensitiveWordMasking> userMaskingMap = Collections.unmodifiableMap(new HashMap<String, SensitiveWordMasking>());

    public void refreshWords() {
        SensitiveWordMasking loadDefaultMasking = loadDefaultMasking(defaultMasking);
        if (loadDefaultMasking != null) {
            defaultMasking = loadDefaultMasking;
        }
        if (!MaskingContext.context().isMultiple()) {
            return;
        }

        Map<String, SensitiveWordMasking> _maskingMap = reloadUserMasking(userMaskingMap);
        if (_maskingMap != null || !_maskingMap.isEmpty()) {
            userMaskingMap = Collections.unmodifiableMap(_maskingMap);
        }
    }

    @Override
    public void free() {
        defaultMasking = null;
        userMaskingMap = Collections.unmodifiableMap(new HashMap<String, SensitiveWordMasking>());
    }

    protected abstract Map<String, SensitiveWordMasking> reloadUserMasking(Map<String, SensitiveWordMasking> userMaskingMap);

    protected abstract SensitiveWordMasking loadDefaultMasking(SensitiveWordMasking defaultMasking);
}
